home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / programm.ing / ams__l~1.zoo / src / timer.cc < prev   
Encoding:
C/C++ Source or Header  |  1993-09-05  |  2.1 KB  |  117 lines

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. //  This file is part of the Atari Machine Specific Library,
  4. //  and is Copyright 1992 by Warwick W. Allison.
  5. //
  6. //  You are free to copy and modify these sources, provided you acknowledge
  7. //  the origin by retaining this notice, and adhere to the conditions
  8. //  described in the file COPYING.
  9. //
  10. //////////////////////////////////////////////////////////////////////////////
  11.  
  12. #include "Timer.h"
  13. #include <stdio.h>
  14. #include <osbind.h>
  15. #include <builtin.h>
  16. #include <sysvars.h>
  17.  
  18.  
  19. // TERMINATION code:
  20.  
  21. // used to ensure DisplayRestorer is linked in if possibly necessary
  22. #define EnsureRestoration { volatile TimerRestorer* x=&MyTimerRestorer; }
  23.  
  24. class TimerRestorer
  25. {
  26. public:
  27.     TimerRestorer() { };
  28.     ~TimerRestorer() {
  29.         HaltTimerA();
  30.     };
  31. };
  32.  
  33. static TimerRestorer MyTimerRestorer;
  34.  
  35.  
  36.  
  37. unsigned long hz200;
  38.  
  39. void GetHz200()
  40. {
  41.     hz200=*_hz_200;
  42. }
  43.  
  44. unsigned long Hz200()
  45. {
  46.     Supexec(GetHz200);
  47.     return hz200;
  48. }
  49.  
  50.  
  51. void Delay(unsigned long msec)
  52. {
  53.     msec=msec/5;
  54.  
  55.     unsigned long Start=Hz200();
  56.     while (Start+msec > Hz200());
  57. }
  58.  
  59.  
  60.  
  61.  
  62. const MainClock=2457600; /* As gleaned from $FC21DC in BIOS */
  63.  
  64. const short Subdivider[]={000,4,10,16,50,64,100,200}; // First unused
  65.  
  66. TimerSpeed::TimerSpeed(int Hz)
  67. {
  68.     if (Hz==0) {
  69.         Control=0;
  70.         Data=0;
  71.     } else {
  72.         unsigned Granularity;
  73.         unsigned MaxError,Error,DataRequired;
  74.         short Mode;
  75.  
  76.         MaxError=99999999;
  77.         Data=255;    // Best we can do is 82Hz
  78.         Control=7;
  79.  
  80.         for (Mode=1; Mode<=7; Mode++) {
  81.             Granularity=MainClock / Subdivider[Mode];
  82.             DataRequired=Granularity / Hz;
  83.             if (DataRequired < 256) {
  84.                 Error=abs(Granularity / DataRequired - Hz);
  85.                 if (Error < MaxError) {
  86.                     Control=Mode;
  87.                     Data=DataRequired;
  88.                     MaxError=Error;
  89.                 }
  90.             }
  91.         }
  92.     }
  93. }
  94.  
  95. TimerSpeed::operator int()
  96. {
  97.     unsigned Granularity=MainClock / Subdivider[Control];
  98.     return Granularity / Data;
  99. }
  100.  
  101. void HaltTimerA()
  102. {
  103.     Xbtimer(0,0,0,0);
  104. }
  105.  
  106. void SetTimerA(void ISR(), TimerSpeed& S)
  107. {
  108.     EnsureRestoration;
  109.     Xbtimer(0,S.Control,S.Data,ISR);
  110. }
  111.  
  112. void SetTimerA(void ISR(), int Hz)
  113. {
  114.     if (Hz) SetTimerA(ISR,TimerSpeed(Hz));
  115.     else HaltTimerA();
  116. }
  117.